using System;
using System.Collections.Generic;
using System.Text;
using BizTalkCop.Rules.Bases;
using Microsoft.FxCop.Sdk;
using Microsoft.BizTalk.ExplorerOM;

namespace BizTalkCop.Rules.Naming.Rules
{
    /// <summary>
    /// Rule verifying port names are correctly prefixed "Send." or "Receive."
    /// </summary>
    public class PortNamesShouldIndicateDirection : ApplicationRuleBase
    {
        /// <summary>
        /// Default constructor
        /// </summary>
        public PortNamesShouldIndicateDirection() : base("PortNamesShouldIndicateDirection") { }

        /// <summary>
        /// Checks if the port name is correctly prefixed
        /// </summary>
        /// <param name="application">Application to check</param>
        /// <returns>Problem collection</returns>
        protected override ProblemCollection Check(Application application)
        {
            string prefix = this.GetConfiguredSetting(Setting.ReceivePrefix);
            foreach (ReceivePort receivePort in application.ReceivePorts)
            {
                this.CheckName(receivePort.Name, prefix, application);
            }

            prefix = this.GetConfiguredSetting(Setting.SendPrefix);
            foreach (SendPort sendPort in application.SendPorts)
            {
                this.CheckName(sendPort.Name, prefix, application);
            }

            return Problems;
        }

        private void CheckName(string name, string prefix, Application application)
        {
            if (!MemberName.IsGeneratedName(name) && !name.StartsWith(prefix))
            {
                Problems.Add(new Problem(GetNamedResolution("Prefix", name, prefix), application.Name));
            }
        }

        #region Configured settings

        static PortNamesShouldIndicateDirection()
        {
            Dictionary<string, string> defaults = new Dictionary<string, string>();
            defaults.Add(Setting.ReceivePrefix, Default.Receive);
            defaults.Add(Setting.SendPrefix, Default.Send);
            SetDefaults(typeof(PortNamesShouldIndicateDirection), defaults);
        }

        private struct Setting
        {
            public const string ReceivePrefix = "ReceivePrefix";
            public const string SendPrefix = "SendPrefix";
        }

        private struct Default
        {
            public const string Receive = "Receive.";
            public const string Send = "Send.";
        }

        #endregion
    }
}
